#!/bin/bash
#####################################################################
# 功能：通用管理面板
# 作者：wurenlong & Copilot Pro
# 版本：1.0.0
#####################################################################

# 设置中文环境
export LANG="zh_CN.UTF-8"

# 获取脚本真实路径
SCRIPT_PATH=""
if [ -L "$0" ]; then
    # 如果是符号链接，获取真实路径
    SCRIPT_PATH=$(readlink -f "$0")
else
    # 如果是直接运行脚本，获取绝对路径
    SCRIPT_PATH=$(realpath "$0")
fi
# 获取脚本所在目录
SCRIPT_DIR=$(dirname "$SCRIPT_PATH")
# 配置文件路径
CONFIG_FILE="$SCRIPT_DIR/services.conf"

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 检查配置文件是否存在
if [ ! -f "$CONFIG_FILE" ]; then
    echo -e "${RED}错误：配置文件不存在！请添加配置文件：$CONFIG_FILE。${NC}"
    exit 1
fi

# 处理配置文件中的Windows换行符
dos2unix "$CONFIG_FILE" 2>/dev/null || sed -i 's/\r//' "$CONFIG_FILE"

# 加载配置文件
source "$CONFIG_FILE"

# 获取所有配置的应用
declare -a APP_LIST
for var in $(compgen -v | grep "^app[0-99]*_name"); do
    app_num=${var%_*}
    APP_LIST+=("$app_num")
done

# 获取系统默认的Java环境变量
get_system_java_home() {
    if command -v java >/dev/null 2>&1; then
        local _java_home=$(dirname $(dirname $(readlink -f $(which java))))
        echo "$_java_home"
        return 0
    else
        echo -e "${RED}未配置${NC}" >&2
        return 1
    fi
}

# 测试端口是否使用中
is_port_in_use() {
    local port=$1
    if [ -z "$port" ]; then
        return 1
    fi
    if lsof -i:"$port" >/dev/null 2>&1; then
        return 0
    else
        return 1
    fi
}

# 拼接路径
join_paths() {
    local path1="${1:-}" # 工作目录路径
    local path2="${2:-}" # 文件路径
    
    # 两个路径都为空，返回空字符串
    if [ -z "$path1" ] && [ -z "$path2" ]; then
        echo ""
        return 0
    fi
    
    # 只有一个路径有值，直接返回有值的路径
    if [ -z "$path1" ]; then
        echo "$path2"
        return 0
    fi
    if [ -z "$path2" ]; then
        echo "$path1"
        return 0
    fi
    
    # 如果path2以-开头，表示path2是绝对路径，去除掉-后返回path2即可
    if [[ "$path2" == -* ]]; then
        path2="${path2:1}"  # 去除开头的-
        echo "$path2"
        return 0
    fi
    
    # 标准化路径，移除结尾和开头的多余斜杠
    local norm_path1="${path1%/}"
    local norm_path2="${path2#/}"
    
    # 特殊情况: 如果path1是根目录，不要去除斜杠
    if [ "$path1" = "/" ]; then
        norm_path1="/"
    fi
    
    # 拼接并返回
    echo "${norm_path1}/${norm_path2}"
    return 0
}

# 检查服务状态
check_service_status() {
    local instance=$1
    local pid_file_var="${instance}_pid_file"
    local workdir_var="${instance}_workdir"

    local workdir="${!workdir_var}"
    local pid_file="${!pid_file_var}"
    local pid_file_path=$(join_paths "$workdir" "$pid_file")

    if [ -z "$workdir" ] || ! cd "$workdir" 2>/dev/null; then
        return 1
    fi

    if [ -f "$pid_file_path" ]; then
        pid=$(cat "$pid_file_path")
        if [[ "$pid" =~ ^[0-9]+$ ]] && kill -0 "$pid" 2>/dev/null; then
            echo -e "${GREEN}运行中 (PID: $pid)${NC}"
            return 0
        else
            echo -e "${RED}已停止 (PID文件存在但进程无效: $pid_file_path)${NC}"
            return 1
        fi
    fi
    echo -e "${RED}已停止${NC}"
    return 1
}

# 获取进程ID的通用方法
get_service_pid() {
    local instance=$1
    local workdir_var="${instance}_workdir"
    local pid_file_var="${instance}_pid_file"

    local workdir="${!workdir_var}"
    local _pid_file="${!pid_file_var}"
    local pid=""
    if [ ! -z "$_pid_file" ]; then
        local pid_file=$(join_paths "$workdir" "$_pid_file")
        if [ -f "$pid_file" ]; then
            pid=$(cat "$pid_file")
            # 验证PID是否有效 - 只取第一个PID
            pid=$(echo "$pid" | awk '{print $1}')
            if ps -p $pid > /dev/null 2>&1; then
                echo $pid
                return 0
            else
                # PID文件存在但进程不存在，清理无效的PID文件
                rm -f "$pid_file"
            fi
        fi
    fi
    
    # 如果PID文件不存在或无效，尝试通过进程名查找
    pid=$(pgrep -f "$workdir" | head -n 1)
    if [ -n "$pid" ]; then
        echo $pid
        return 0
    fi
    
    echo ""
    return 1
}

# 获取服务配置的Java环境变量
get_service_java_home() {
    local instance=$1
    local java_home_var="${instance}_java_home"

    # 优先使用实例特定的java_home
    local _java_home="${!java_home_var}"
    if [ -z "$_java_home" ]; then
        if [ -n "$java_home" ]; then
            echo "$java_home"
            return 0
        else
            # 如果没有设置实例特定的java_home，尝试获取系统默认的Java环境变量
            _java_home=$(get_system_java_home "$1")
            if [ -n "$_java_home" ]; then
                echo "$_java_home"
                return 0
            fi
            echo -e "${RED}Java环境变量未设置，请设置java_home变量${NC}" >&2
            return 1
        fi
    fi
    echo "$_java_home"
    return 0
}

# ===== Tomcat服务专用函数 =====
# 检查HTTP状态的通用方法
check_tomcat_http_status() {
    local url=$1
    if [ -z "$url" ]; then
        echo -e "${RED}错误: URL不能为空${NC}"
        return 1
    fi
    # 使用curl检查HTTP状态码
    if ! command -v curl &> /dev/null; then
        echo -e "${RED}错误: curl命令未找到，请安装curl工具${NC}"
        return 1
    fi
    if curl -s -o /dev/null -w "%{http_code}" "$url" | grep -q "200"; then
        return 0  # 返回成功
    else
        return 1  # 返回失败
    fi
}

# 获取Tomcat是否安装守护进程模式
is_install_tomcat_daemon_mode() {
    local instance=$1
    local tomcat_path_var="${instance}_workdir"
    local tomcat_path="${!tomcat_path_var}"
    if [ -z "$tomcat_path" ]; then
        return 1
    fi
    local daemon_script="$tomcat_path/bin/daemon.sh"
    local jsvc_script="$tomcat_path/bin/jsvc"
    if [ -f "$daemon_script" ] && [ -f "$daemon_script" ] && [ -x "$daemon_script" ] && [ -x "$daemon_script" ] ; then
        local _java_home=$(grep "^JAVA_HOME=" "$daemon_script" | grep -v '"\$2"' | grep -v 'dirname' | grep -v 'cd.*pwd' | tail -n 1 | cut -d'=' -f2)
        # 如果JAVA_HOME是用引号括起来的，去掉引号
        _java_home=$(echo "$_java_home" | sed -e 's/^"//' -e 's/"$//')
        # 如果存在多行定义，确保只取最后一个定义的值
        if [[ "$_java_home" == *$'\n'* ]]; then
            _java_home=$(echo "$_java_home" | tail -n 1)
        fi
        if [ -z "$_java_home" ]; then
            echo -e "${RED}Daemon模式已安装，但未配置JAVA_HOME，请检查daemon.sh文件。${NC}"
            return 1
        fi
        if [ ! -x "$_java_home/bin/java" ]; then
            echo -e "${RED}Daemon模式已安装，但JAVA_HOME指向的Java环境变量无效，请检查daemon.sh文件。${NC}"
            echo -e "${RED}无效JAVA_HOME：$_java_home${NC}"
            return 1
        fi
        return 0
    else
        echo -e "${RED}未安装Daemon模式，请先安装。${NC}"
        return 1
    fi
}

# 显示Tomcat是否安装守护进程模式
show_install_tomcat_daemon_mode() {
    local instance=$1
    local tomcat_path_var="${instance}_workdir"
    local tomcat_path="${!tomcat_path_var}"
    if [ -z "$tomcat_path" ]; then
        return 1
    fi
    local daemon_script="$tomcat_path/bin/daemon.sh"
    local jsvc_script="$tomcat_path/bin/jsvc"
    if [ -f "$daemon_script" ] && [ -f "$daemon_script" ] && [ -x "$daemon_script" ] && [ -x "$daemon_script" ] ; then
        local _java_home=$(grep "^JAVA_HOME=" "$daemon_script" | grep -v '"\$2"' | grep -v 'dirname' | grep -v 'cd.*pwd' | tail -n 1 | cut -d'=' -f2)
        _java_home=$(echo "$_java_home" | sed -e 's/^"//' -e 's/"$//')
        if [[ "$_java_home" == *$'\n'* ]]; then
            _java_home=$(echo "$_java_home" | tail -n 1)
        fi
        if [ -z "$_java_home" ]; then
            echo -e "${RED}Daemon模式已安装，但未配置JAVA_HOME，请检查daemon.sh文件。${NC}"
            return 1
        fi
        if [ ! -x "$_java_home/bin/java" ]; then
            echo -e "${RED}Daemon模式已安装，但JAVA_HOME指向的Java环境变量无效，请检查daemon.sh文件。${NC}"
            echo -e "${RED}无效JAVA_HOME：$_java_home${NC}"
            return 1
        fi
        local _java_version=$($_java_home/bin/java -version 2>&1 | awk -F '"' '/version/ {print $2}')
        echo -e "${YELLOW}Daemon模式已安装，JAVA_HOME: ${NC}$_java_home，${YELLOW}JAVA版本${NC}: $_java_version"
        return 0
    else
        echo -e "${RED}未安装Daemon模式，请先安装。${NC}"
        return 1
    fi
}

# 获取节点状态和PID
get_tomcat_status() {
    local instance=$1
    local port_var="${instance}_port"
    local tomcat_path_var="${instance}_workdir"
    local test_url_var="${instance}_test_url"

    local port="${!port_var}"
    local tomcat_path="${!tomcat_path_var}"
    local test_url="${!test_url_var}"

    local pid=$(get_service_pid "$instance")
    local status="停止"
    local http_status="未响应"
    local memory_usage=""
    local cpu_usage=""

    if [ -n "$pid" ]; then
        status="${GREEN}运行中${NC}"
        # 查找所有相关Tomcat进程 - 用于计算总内存和CPU使用
        local all_pids=$(pgrep -f "$tomcat_path")
        # 计算总内存使用
        local total_mem=0
        for p in $all_pids; do
            local mem=$(ps -o rss= -p $p 2>/dev/null)
            if [[ -n "$mem" && "$mem" =~ ^[0-9]+$ ]]; then
                total_mem=$((total_mem + mem))
            fi
        done
        memory_usage=$(awk "BEGIN {printf \"%.2f GB\", $total_mem/1024/1024}")
        
        # 计算总CPU使用
        local total_cpu=0
        for p in $all_pids; do
            local cpu=$(ps -p $p -o %cpu= 2>/dev/null | awk '{print $1}')
            if [[ -n "$cpu" && "$cpu" =~ ^[0-9.]+$ ]]; then
                total_cpu=$(echo "$total_cpu + $cpu" | bc)
            fi
        done
        cpu_usage=$(awk "BEGIN {printf \"%.1f%%\", $total_cpu}")
        
        if check_tomcat_http_status $test_url; then
            http_status="${GREEN}正常${NC}"
        else
            http_status="${RED}异常${NC}"
        fi
    else
        pid="${RED}无${NC}"
    fi

    echo -e "端口: $port, 状态: $status, PID: $pid, HTTP状态: $http_status, CPU: $cpu_usage, 内存: $memory_usage"
}

# 重启Tomcat服务
start_tomcat() {
    local instance=$1
    local name_var="${instance}_name"
    local port_var="${instance}_port"
    local tomcat_path_var="${instance}_workdir"
    local pid_file_var="${instance}_pid_file"
    local test_url_var="${instance}_test_url"

    local name="${!name_var}"
    local port="${!port_var}"
    local tomcat_path="${!tomcat_path_var}"
    local test_url="${!test_url_var}"
    local _pid_file="${!pid_file_var}"
    local pid_file_path=$(join_paths "$tomcat_path" "$_pid_file")

    local startup_timeout=90  # 启动超时时间
    local pid=$(get_service_pid $instance)

    if [ -n "$pid" ]; then
       echo -e "\n${GREEN} ${!name} 服务运行中${NC}"
       return 1
    fi

    # 启动前检查端口
    if netstat -tln | grep -q ":$port "; then
        echo -e "${RED}错误: 端口 $port 已被占用，请检查${NC}"
        return 1
    fi

    # 判断是否已安装Daemon模式
    if ! is_install_tomcat_daemon_mode $instance; then
        echo -e "${RED}错误: 未安装守护进程模式，请先安装守护进程模式。${NC}"
        return 1
    fi
    
    echo -n "正在启动 ${!name}..."
    # 将启动命令放入后台执行，并重定向输出
    nohup $tomcat_path/bin/daemon.sh start > "$tomcat_path/logs/startup.log" 2>&1 &
    
    # 等待启动完成
    local start_time=$SECONDS
    local timeout_time=$((SECONDS + startup_timeout))
    local started=false
    
    while [ $SECONDS -lt $timeout_time ]; do
        echo -n "."
        # 检查PID文件和进程
        if [ -f "$pid_file_path" ]; then
            local new_pid=$(cat "$pid_file_path")
            if ps -p $new_pid > /dev/null 2>&1; then
                if netstat -tln | grep -q ":$port "; then
                    # 显示启动日志中的错误信息
                    if grep -i "error\|exception" "$tomcat_path/logs/startup.log" >/dev/null; then
                        echo -e "\n${YELLOW}警告: 启动过程中发现错误:${NC}"
                        grep -i "error\|exception" "$tomcat_path/logs/startup.log" | tail -n 3
                    fi
                    
                    # 验证服务是否响应
                    if check_tomcat_http_status $test_url; then
                        echo -e "\n${GREEN}服务已成功启动 (用时: $((SECONDS - start_time))秒)${NC}"
                        started=true
                        break
                    fi
                fi
            fi
        fi
        sleep 1
    done
    
    if ! $started; then
        echo -e "\n${RED}错误: 服务启动失败或响应超时${NC}"
        echo "诊断信息:"
        echo "1. PID文件: $([ -f "$pid_file_path" ] && echo "存在" || echo "不存在")"
        echo "2. 进程状态: $(ps aux | grep "$tomcat_path" | grep -v grep || echo "未运行")"
        echo "3. 端口状态: $(netstat -tln | grep "$port" || echo "未监听")"
        echo "4. 最近日志:"
        tail -n 5 "$tomcat_path/logs/catalina-daemon.out"
        return 1
    fi
    
    get_tomcat_status "$instance"
    return 0
}

# 关闭Tomcat服务
stop_tomcat() {
    local max_wait_time=60  # 最大等待时间
    local instance=$1
    local tomcat_path_var="${instance}_workdir"

    local tomcat_path="${!tomcat_path_var}"
    local pid=$(get_service_pid $instance)
    
    if [ -n "$pid" ]; then
        # 判断是否已安装Daemon模式
        if ! is_install_tomcat_daemon_mode $instance; then
            echo -e "${RED}错误: 未安装守护进程模式，请先安装守护进程模式。${NC}"
            return 1
        fi

        echo -n "正在停止 $node..."
        nohup $tomcat_path/bin/daemon.sh stop > "$tomcat_path/logs/startup.log" 2>&1 &
        
        local count=0
        while [ $count -lt $max_wait_time ]; do
            if ! ps -p $pid > /dev/null 2>&1; then
                echo -e "\n${GREEN}服务已停止${NC}"
                break
            fi
            echo -n "."
            sleep 1
            count=$((count + 1))
        done

        if [ $count -eq $max_wait_time ]; then
            echo -e "\n${RED}警告: 服务停止超时,尝试强制终止进程...${NC}"
            # 终止所有相关进程，不仅仅是主进程
            local all_pids=$(pgrep -f "$tomcat_path")
            if [ -n "$all_pids" ]; then
                for p in $all_pids; do
                    kill -9 $p 2>/dev/null
                done
                echo -e "${GREEN}已强制终止所有相关进程${NC}"
            else
                kill -9 $pid 2>/dev/null
                echo -e "${GREEN}已强制终止主进程${NC}"
            fi
            sleep 1
        fi
    else 
        echo -e "\n${GREEN}服务已停止${NC}"
    fi
}

# 重启Tomcat服务
restart_tomcat() {
    local instance=$1
    local name_var="${instance}_name"
    local port_var="${instance}_port"
    local name="${!name_var}"
    local port="${!port_var}"

    # 判断是否已安装Daemon模式
    if ! is_install_tomcat_daemon_mode $instance; then
        echo -e "${RED}错误: 未安装守护进程模式，请先安装守护进程模式。${NC}"
        return 1
    fi

    stop_tomcat "$instance"

    # 递归判断端口是否被占用
    while is_port_in_use "$port"; do
        sleep 1
    done
    
    echo -e "${YELLOW}端口 $port 已释放，准备重启 $name 服务...${NC}"

    start_tomcat "$instance"
    
    if [ $? -eq 0 ] && [ ! $(is_port_in_use "$port") ]; then
        echo -e "${GREEN} $name - 服务已成功重启${NC}"
        return 0
    else
        echo -e "${RED}错误: $name - 服务重启失败${NC}"
        return 1
    fi
}

# 日志管理
view_tomcat_logs() {
    local instance=$1
    local name_var="${instance}_name"
    local tomcat_path_var="${instance}_workdir"
    local log_file_var="${instance}_log_file"

    local name="${!name_var}"
    local tomcat_path="${!tomcat_path_var}"
    local log_file="${!log_file_var}"
    local log_file_path=$(join_paths "$tomcat_path" "$log_file")
    
    clear
    echo "===== ${name} 日志查看 ====="
    echo "1: 实时查看最新日志"
    echo "b: 返回"
    
    read -e -p "请选择: " log_choice
    case $log_choice in
        1)
            echo "查看实时日志 (Ctrl+C 退出)..."
            # 确保log_file_val存在，否则使用默认的catalina-daemon.out
            if [ -n "$log_file_path" ] && [ -f "$log_file_path" ]; then
                tail -f "$log_file_path"
            else
                tail -f "$tomcat_path/logs/catalina-daemon.out"
            fi
            ;;
        b)
            return 0
            ;;
    esac
}

# 安装Tomcat守护进程模式
install_tomcat_daemon_mode() {
    local instance=$1
    local name_var="${instance}_name"
    local workdir_var="${instance}_workdir"

    local name="${!name_var}"
    local _java_home=$(get_service_java_home "$instance")
    local workdir="${!workdir_var}"
    local binDir="${workdir}/bin"

    if [ -z "$workdir" ]; then
        echo -e "${RED}工作目录未设置，无法安装守护进程模式！${NC}"
        return 1
    fi
    
    if [ ! -f "$binDir/daemon.sh" ]; then
        if [ -f "$binDir/daemon.sh.bak" ]; then
            cp "$binDir/daemon.sh.bak" "$binDir/daemon.sh"
        else
            echo -e "${RED}错误: 缺少$binDir/daemon.sh文件，请重新安装Tomcat！${NC}"
            return 1
        fi
    fi

    if [ ! -x "$binDir/daemon.sh" ]; then
        chmod +x "$binDir/daemon.sh"
    fi

    if [ -f "$binDir/jsvc" ]; then
        if [ ! -x "$binDir/jsvc" ]; then 
            chmod +x "$binDir/jsvc"
        fi 
        echo -e "${YELLOW}警告: $binDir/jsvc 已存在，可能是之前安装过守护进程模式。${NC}"
        read -p "是否覆盖安装？(y|n): " confirm
        if [ "$confirm" != "y" ]; then
            echo -e "${RED}取消安装守护进程模式。${NC}"
            return 0
        else
            if [ -f "$binDir/daemon.sh.bak" ]; then
                cp "$binDir/daemon.sh.bak" "$binDir/daemon.sh"
            fi
        fi
    fi
    
    # 检查必要文件是否存在
    if [ ! -f "$binDir/commons-daemon-native.tar.gz" ]; then
        echo -e "${RED}找不到commons-daemon-native.tar.gz文件！${NC}"
        return 1
    fi

    local tomcat_user="root"
    local xms="256m"
    local xmx="2048m"
    
    while true; do
        read -p "请输入JAVA_HOME值(例如:/data/jdk1.8.0_411, 默认${_java_home}): " input_java_home
        if [ -z "$input_java_home" ]; then
            break
        else
            if [ -d "$input_java_home" ] && [ -f "$input_java_home/bin/java" ]; then
                _java_home="$input_java_home"
                break
            else
                echo -e "${RED}请输入正确的JAVA_HOME路径。${NC}"
            fi
        fi
    done
    if [ ! -d "$_java_home" ]; then
        echo -e "${RED}Java环境变量无效，请检查$_java_home。${NC}"
        return 1
    fi
    # 判断 java_home 不能为空
    if [ ! -f "$_java_home/bin/java" ] || [ ! -x "$_java_home/bin/java" ]; then
        echo -e "${RED}Java环境变量无效，请检查$_java_home/bin/java。${NC}"
        return 1
    fi
   
    while true; do
        read -p "请输入TOMCAT_USER值(例如:tomcat,root, 默认${tomcat_user}): " input_tomcat_user
        if [ -z "$input_tomcat_user" ]; then
            break
        else
            # 判断输入用户是否存在
            if id "$input_tomcat_user" &>/dev/null; then
                tomcat_user="$input_tomcat_user"
                break
            else
                echo -e "${RED}[$input_tomcat_user]用户不存在${NC}"
            fi
        fi
    done
    if ! $(id "$tomcat_user" &>/dev/null); then
        echo -e "${RED}[$tomcat_user]用户不存在${NC}"
    fi

    while true; do
        read -p "请输入最小内存值(例如:256m,1g, 默认${xms}): " input_xms
        if [ -z "$input_xms" ]; then
            break
        else
            if [[ "$input_xms" =~ ^[0-9]+[mMgG]$ ]]; then
                xms="$input_xms"
            else
                echo -e "${RED}输入格式错误，例如:256m,1g${NC}"
            fi
        fi
    done

    while true; do
        read -p "请输入最大内存值(例如:2048m,2g, 默认${xmx}): " input_xmx
        if [ -z "$input_xmx" ]; then
            break
        else
            if [[ "$input_xmx" =~ ^[0-9]+[mMgG]$ ]]; then
                xmx="$input_xmx"
            else
                echo -e "${RED}输入格式错误，例如:2048m,2g${NC}"
            fi
        fi
    done

    # 确认安装环境、
    echo -e "${YELLOW}安装环境:${NC}"
    echo -e "工作目录: ${GREEN}$workdir${NC}"
    echo -e "JAVA_HOME: ${GREEN}$_java_home${NC}"
    echo -e "TOMCAT_USER: ${GREEN}$tomcat_user${NC}"
    echo -e "最小内存: ${GREEN}$xms${NC}"
    echo -e "最大内存: ${GREEN}$xmx${NC}"
    echo -e "${YELLOW}是否继续安装？${NC}"
    read -p "请确认安装环境？(y|n): " confirm
    if [ "$confirm" != "y" ]; then
        echo -e "${RED}取消安装守护进程模式。${NC}"
        return 0
    fi

    echo "正在安装 $name 的守护进程模式..."

    # 解压daemon源码
    cd "$binDir"
    tar xzf commons-daemon-native.tar.gz
    
    # 找到解压后的目录
    local daemon_src_dir=$(find . -maxdepth 1 -type d -name "commons-daemon-*-native-src" | head -n 1)
    if [ -z "$daemon_src_dir" ]; then
        echo -e "${RED}无法找到解压后的commons-daemon目录！${NC}"
        return 1
    fi

    # 编译jsvc
    cd "$daemon_src_dir/unix"
    ./configure --with-java="$_java_home"
    if [ $? -ne 0 ]; then
        echo -e "${RED}配置编译环境失败！${NC}"
        return 1
    fi

    make
    if [ $? -ne 0 ]; then
        echo -e "${RED}编译失败！${NC}"
        return 1
    fi

    # 复制jsvc到bin目录
    cp jsvc "$binDir/"
    chmod +x "$binDir/jsvc"

     # 修改daemon.sh配置
    if [ -f "$binDir/daemon.sh" ]; then

        if [ ! -f "$binDir/daemon.sh.bak" ]; then
            # 备份原始文件
            cp "$binDir/daemon.sh" "$binDir/daemon.sh.bak"
        fi

        # 更新默认用户
        sed -i 's/test ".$TOMCAT_USER" = . && TOMCAT_USER=tomcat/test ".$TOMCAT_USER" = . \&\& TOMCAT_USER='"$tomcat_user"'/' "$binDir/daemon.sh"
        
        # 在PRG="$0"行后添加JAVA_HOME配置
        sed -i '/^PRG="$0"$/a JAVA_HOME='"$_java_home" "$binDir/daemon.sh"
        
        sed -i '0,/^JAVA_OPTS=/s|^JAVA_OPTS=.*|JAVA_OPTS="-Xms'"$xms"' -Xmx'"$xmx"' -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 -Duser.language=zh -Duser.region=CN -Duser.timezone=Asia/Shanghai -Dorg.apache.catalina.security.SecurityListener.UMASK=0022"|' "$binDir/daemon.sh"
        
        chmod +x "$binDir/daemon.sh"
    else
        echo -e "${RED}daemon.sh文件不存在！${NC}"
        return 1
    fi

    # 清理临时文件
    rm -rf "$binDir/$daemon_src_dir"
    # 删除旧的启动脚本
    rm -f "$binDir/startup.sh" "$binDir/shutdown.sh"

    echo -e "${GREEN} $name 守护进程模式安装完成！${NC}"
    return 0
}

show_tomcat_menu() {
    local instance=$1
    local name="${instance}_name"
    while true; do
        clear
        echo -e "${BLUE}===============================================${NC}"
        echo -e "${YELLOW}        Tomcat管理: ${!name}            ${NC}"
        echo -e "${BLUE}===============================================${NC}"

        get_tomcat_status "$instance"

        echo -e "${BLUE}-----------------------------------------------${NC}"
    
        show_install_tomcat_daemon_mode "$instance"

        echo -e "${BLUE}-----------------------------------------------${NC}"
        echo -e "${YELLOW}1)${NC} 启动服务"
        echo -e "${YELLOW}2)${NC} 停止服务"
        echo -e "${YELLOW}3)${NC} 重启服务"
        echo -e "${YELLOW}4)${NC} 查看日志"
        echo -e "${YELLOW}9)${NC} 安装Daemon模式"
        echo -e "${YELLOW}0)${NC} 返回主菜单"
        echo -e "${BLUE}-----------------------------------------------${NC}"
        read -e -p "请输入选项: " choice
        case $choice in
            1)
                read -p "确认要启动吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    start_tomcat "$instance"
                    read -p "按回车继续..."
                fi
                ;;
            2)
                read -p "确认要停止吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    stop_tomcat "$instance"
                    read -p "按回车继续..."
                fi
                ;;
            3)
                read -p "确认要重启吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    restart_tomcat "$instance"
                    read -p "按回车继续..."
                fi
                ;;
            4)
                view_tomcat_logs "$instance"
                ;;
            9)
                read -p "确认要安装守护进程模式吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    install_tomcat_daemon_mode "$instance"
                    read -p "按回车继续..."
                fi
                ;;
            0|b|B)
                break
                ;;
            *)
                echo "无效选项"
                ;;
        esac
    done
}

# ===== Nginx服务专用函数 =====
get_nginx_status() {
    local instance=$1
    local name_var="${instance}_name"
    local nginx_path_var="${instance}_workdir"
    local nginx_conf_path_var="${instance}_conf_file"

    local name="${!name_var}"
    local nginx_path="${!nginx_path_var}"
    local _nginx_conf_file="${!nginx_conf_path_var}"
    local nginx_conf_file=$(join_paths "$nginx_path" "$_nginx_conf_file")

    # 确定配置文件路径
    if [ -z "$nginx_conf_file" ] || [ ! -f "$nginx_conf_file" ]; then
        nginx_conf_file="$nginx_path/conf/nginx.conf"
    fi
    
    # 检查必要路径和文件
    if [ ! -d "$nginx_path" ]; then
        echo -e "${RED}错误: Nginx工作目录不存在: '$nginx_path'${NC}"
        return 1
    fi
    
    if [ ! -f "$nginx_conf_file" ]; then
        echo -e "${RED}错误: Nginx配置文件不存在: '$nginx_conf_file'${NC}"
        return 1
    fi
    
    # 获取进程状态
    local pid=$(get_service_pid $instance)
    local status_text="${RED}未运行${NC}"
    local version_info=""
    local worker_count=0
    local connections=0
    
    if [ -n "$pid" ]; then
        status_text="${GREEN}运行中${NC}"
        
        # 获取版本信息
        if [ -x "$nginx_path/sbin/nginx" ]; then
            version_info=$($nginx_path/sbin/nginx -v 2>&1)
            version_info=$(echo $version_info | grep -oP "nginx/\K[0-9]+\.[0-9]+\.[0-9]+" || echo "未知")
            
            # 获取worker进程数量
            worker_count=$(pgrep -f "nginx: worker" | wc -l)
            
            # 尝试获取连接数
            if command -v ss >/dev/null 2>&1; then
                connections=$(ss -nat | grep -i nginx | wc -l)
            elif command -v netstat >/dev/null 2>&1; then
                connections=$(netstat -nat | grep -i nginx | wc -l)
            fi
        fi
        
        echo -e "${GREEN}[$name] Nginx状态: $status_text${NC}"
        echo -e "PID: ${GREEN}$pid${NC} | 版本: ${GREEN}$version_info${NC} | Worker进程: ${GREEN}$worker_count${NC} | 当前连接: ${GREEN}$connections${NC}"
        
        # 检查nginx配置是否有语法错误
        if [ -x "$nginx_path/sbin/nginx" ]; then
            echo -n "配置语法检查: "
            if $nginx_path/sbin/nginx -t -c "$nginx_conf_file" >/dev/null 2>&1; then
                echo -e "${GREEN}正常${NC}"
            else
                echo -e "${RED}存在错误${NC} (运行 'nginx -t' 查看详情)"
            fi
        fi
    else
        echo -e "${RED}[$name] Nginx状态: $status_text${NC}"
    fi
    
    return 0
}

start_nginx() { 
    local instance=$1
    local name_var="${instance}_name"
    local nginx_path_var="${instance}_workdir"
    local nginx_conf_path_var="${instance}_conf_file"

    local name="${!name_var}"
    local nginx_path="${!nginx_path_var}"
    local _nginx_conf_file="${!nginx_conf_path_var}"
    local nginx_conf_file=$(join_paths "$nginx_path" "$_nginx_conf_file")

    if [ ! -f "$nginx_conf_file" ]; then
        nginx_conf_file="$nginx_path/conf/nginx.conf"
    fi
    
    local pid=$(get_service_pid $instance)
    if [ -n "$pid" ]; then
        echo -e "${YELLOW}[$name] Nginx服务运行中${NC}"
        return 0
    fi
    if [ ! -d "$nginx_path/sbin" ]; then
        echo -e "${RED}错误: Nginx工作目录不存在: '$nginx_path/sbin'${NC}"
        return 1
    fi
    if [ ! -x "$nginx_path/sbin/nginx" ]; then
        echo -e "${RED}错误: Nginx可执行文件不存在或没有执行权限: '$nginx_path/sbin/nginx'${NC}"
        return 1
    fi
    if [ ! -f "$nginx_conf_file" ]; then
        echo -e "${RED}错误: Nginx配置文件不存在: '$nginx_conf_file'${NC}"
        return 1
    fi
    
    echo -e "${BLUE}正在启动 Nginx 服务...${NC}"
    
    $nginx_path/sbin/nginx -c "$nginx_conf_file"
    
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}Nginx服务已成功启动${NC}"
        return 0
    else
        echo -e "${RED}错误: Nginx服务启动失败${NC}"
        return 1
    fi
}

stop_nginx() {
    local instance=$1
    local name_var="${instance}_name"
    local nginx_path_var="${instance}_workdir"

    local name="${!name_var}"
    local nginx_path="${!nginx_path_var}"
    local pid=$(get_service_pid $instance)
    if [ -z "$pid" ]; then
        echo -e "${YELLOW}[$name] Nginx服务未运行${NC}"
        return 0
    fi
    if [ ! -d "$nginx_path/sbin" ]; then
        echo -e "${RED}错误: Nginx工作目录不存在: '$nginx_path/sbin'${NC}"
        return 1
    fi
    if [ ! -x "$nginx_path/sbin/nginx" ]; then
        echo -e "${RED}错误: Nginx可执行文件不存在或没有执行权限: '$nginx_path/sbin/nginx'${NC}"
        return 1
    fi
    
    echo -e "${BLUE}正在停止 Nginx 服务...${NC}"
    
    $nginx_path/sbin/nginx -s stop
    
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}Nginx服务已成功停止${NC}"
        return 0
    else
        echo -e "${RED}错误: Nginx服务停止失败${NC}"
        return 1
    fi
}

restart_nginx() {
    local instance=$1
    local name_var="${instance}_name"
    
    local name="${!name_var}"
    local pid=$(get_service_pid $instance)

    echo -e "${BLUE}正在重启 Nginx 服务...${NC}"
    
    stop_nginx "$instance"
    sleep 2
    start_nginx "$instance"
    
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}Nginx服务已成功重启${NC}"
        return 0
    else
        echo -e "${RED}错误: Nginx服务重启失败${NC}"
        return 1
    fi
}

reload_nginx() {
    local instance=$1
    local name_var="${instance}_name"
    local nginx_path_var="${instance}_workdir"

    local name="${!name_var}"
    local nginx_path="${!nginx_path_var}"
    local pid=$(get_service_pid $instance)

    if [ -z "$pid" ]; then
        echo -e "${YELLOW}[$name] Nginx服务未运行${NC}"
        return 0
    fi
    echo -e "${BLUE}正在热重载 Nginx 配置...${NC}"
    
    $nginx_path/sbin/nginx -s reload
    
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}Nginx配置已成功热重载${NC}"
        return 0
    else
        echo -e "${RED}错误: Nginx配置热重载失败${NC}"
        return 1
    fi
}

test_nginx_config() {
    local instance=$1
    local name_var="${instance}_name"
    local nginx_path_var="${instance}_workdir"
    local nginx_conf_path_var="${instance}_conf_file"
    
    local name="${!name_var}"
    local nginx_path="${!nginx_path_var}"
    local _nginx_conf_file="${!nginx_conf_path_var}"
    local nginx_conf_file=$(join_paths "$nginx_path" "$_nginx_conf_file")

    if [ ! -f "$nginx_conf_file" ]; then
        nginx_conf_file="${!nginx_path}/conf/nginx.conf"
    fi
    
    local pid=$(get_service_pid $instance)
    if [ -z "$pid" ]; then
        echo -e "${YELLOW}[$name] Nginx服务未运行${NC}"
        return 0
    fi
    echo -e "${BLUE}正在测试 Nginx 配置语法...${NC}"
    
    $nginx_path/sbin/nginx -t -c "$nginx_conf_file"
    
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}Nginx配置语法正确${NC}"
        return 0
    else
        echo -e "${RED}错误: Nginx配置语法错误${NC}"
        return 1
    fi
}

show_nginx_menu() {
    local instance=$1
    local name="${instance}_name"
    
    while true; do
        clear
        echo -e "${BLUE}===============================================${NC}"
        echo -e "${YELLOW}        Nginx管理: ${!name}            ${NC}"
        echo -e "${BLUE}===============================================${NC}"

        get_nginx_status "$instance"

        echo -e "${BLUE}-----------------------------------------------${NC}"
        echo -e "${YELLOW}1)${NC} 启动服务"
        echo -e "${YELLOW}2)${NC} 停止服务"
        echo -e "${YELLOW}3)${NC} 重启服务"
        echo -e "${YELLOW}4)${NC} 热重载配置"
        echo -e "${YELLOW}5)${NC} 测试配置语法"
        echo -e "${YELLOW}0)${NC} 返回主菜单"
        echo -e "${BLUE}-----------------------------------------------${NC}"
        read -e -p "请选择操作: " op
                
        case "$op" in
            1) start_nginx "$instance"; break ;;
            2) stop_nginx "$instance"; break ;;
            3) restart_nginx "$instance"; break ;;
            4) reload_nginx "$instance"; break ;;
            5) test_nginx_config "$instance"; break ;;
            0|b|B) return ;;
            *) echo -e "${RED}无效的选择${NC}" ;;
        esac
    done
}

# ===== ActiveMQ服务专用函数 =====
get_activemq_status() { 
    local instance=$1
    local name_var="${instance}_name"
    local activemq_path_var="${instance}_workdir"
    
    local name="${!name_var}"
    local activemq_path="${!activemq_path_var}"
    
    # 获取进程状态
    local pid=$(get_service_pid $instance)
    local status_text="${RED}未运行${NC}"
    local version_info=""
    local mem_usage=""
    local uptime=""
    
    if [ -n "$pid" ]; then
        status_text="${GREEN}运行中${NC}"
        
        # 尝试获取版本信息
        if [ -f "$activemq_path/bin/activemq" ]; then
            version_info=$($activemq_path/bin/activemq --version 2>&1 | head -1 | grep -oP "(\d+\.\d+\.\d+)" || echo "未知")
        fi
        
        # 获取内存使用
        if [ -n "$pid" ]; then
            mem_usage=$(ps -o rss= -p $pid 2>/dev/null)
            if [ -n "$mem_usage" ]; then
                mem_usage=$(awk "BEGIN {printf \"%.2f GB\", $mem_usage/1024/1024}")
            else
                mem_usage="未知"
            fi
        fi
        
        # 获取运行时间
        if [ -n "$pid" ]; then
            local proc_start=$(ps -p $pid -o lstart= 2>/dev/null)
            if [ -n "$proc_start" ]; then
                local start_seconds=$(date -d "$proc_start" +%s)
                local current_seconds=$(date +%s)
                local seconds_running=$((current_seconds - start_seconds))
                local days=$((seconds_running / 86400))
                local hours=$(( (seconds_running % 86400) / 3600 ))
                local minutes=$(( (seconds_running % 3600) / 60 ))
                uptime="${days}天 ${hours}小时 ${minutes}分钟"
            else
                uptime="未知"
            fi
        fi
        
        echo -e "${GREEN}[$name] 状态: $status_text${NC}"
        echo -e "PID: ${GREEN}$pid${NC} | 版本: ${GREEN}$version_info${NC} | 内存: ${GREEN}$mem_usage${NC} | 运行时间: ${GREEN}$uptime${NC}"
        
        local port=$(netstat -tlnp 2>/dev/null | grep "$pid/java" | grep -oP ":[0-9]+" | tr -d ":" | head -1)
        if [ -n "$port" ]; then
            echo -e "监听端口: ${GREEN}$port${NC}"
        fi
    else
        echo -e "${RED}[$name] 状态: $status_text${NC}"
    fi
    
    return 0
}

start_activemq() {
    local instance=$1
    local name_var="${instance}_name"
    local activemq_path_var="${instance}_workdir"
    local pid_file_var="${instance}_pid_file"
    
    local name="${!name_var}"
    local activemq_path="${!activemq_path_var}"
    local _pid_file="${!pid_file_var}"
    local pid_file=$(join_paths "$activemq_path" "$_pid_file")

    local pid=$(get_service_pid $instance)
    
    if [ -n "$pid" ]; then
        echo -e "${YELLOW}[$name] ActiveMQ服务运行中${NC}"
        return 0
    fi
    
    if [ ! -d "$activemq_path/bin" ]; then
        echo -e "${RED}错误: ActiveMQ工作目录不存在: '$activemq_path/bin'${NC}"
        return 1
    fi
    
    echo -e "${BLUE}正在启动 ActiveMQ 服务...${NC}"
    
    nohup $activemq_path/bin/activemq start > "$activemq_path/data/startup.log" 2>&1 &
    
    sleep 5  # 等待服务启动
    
    get_activemq_status $instance
}

stop_activemq() {
    local instance=$1
    local name_var="${instance}_name"
    local activemq_path_var="${instance}_workdir"
    local pid_file_var="${instance}_pid_file"
    
    local name="${!name_var}"
    local activemq_path="${!activemq_path_var}"
    local _pid_file="${!pid_file_var}"
    local pid_file=$(join_paths "$activemq_path" "$_pid_file")

    local pid=$(get_service_pid $instance)
    
    if [ -z "$pid" ]; then
        echo -e "${YELLOW}[$name] ActiveMQ服务未运行${NC}"
        return 0
    fi
    
    echo -e "${BLUE}正在停止 ActiveMQ 服务...${NC}"
    
    nohup $activemq_path/bin/activemq stop > "$activemq_path/data/shutdown.log" 2>&1 &
    
    sleep 5  # 等待服务停止
    
    get_activemq_status $instance
}

restart_activemq() { 
    local instance=$1
    local name_var="${instance}_name"
    local name="${!name_var}"
    
    echo -e "${BLUE}正在重启 ActiveMQ 服务...${NC}"
    
    stop_activemq "$instance"
    sleep 2
    start_activemq "$instance"
    
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}ActiveMQ服务已成功重启${NC}"
        return 0
    else
        echo -e "${RED}错误: ActiveMQ服务重启失败${NC}"
        return 1
    fi
}

show_activemq_menu() {
    local instance=$1
    local name_var="${instance}_name"
    local name="${!name_var}"
    while true; do 
        clear
        echo -e "${BLUE}===============================================${NC}"
        echo -e "${YELLOW}        ActiveMQ管理: $name            ${NC}"
        echo -e "${BLUE}===============================================${NC}"

        get_activemq_status "$instance"

        echo -e "${BLUE}-----------------------------------------------${NC}"
        echo -e "${YELLOW}1)${NC} 启动服务"
        echo -e "${YELLOW}2)${NC} 停止服务"
        echo -e "${YELLOW}3)${NC} 重启服务"
        echo -e "${YELLOW}0)${NC} 返回主菜单"
        echo -e "${BLUE}-----------------------------------------------${NC}"
        read -e -p "请选择操作: " op
        case "$op" in
            1) 
                read -p "确认要启动吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    start_activemq "$instance"
                    return 0
                fi
                return 1
                ;;
            2)
                read -p "确认要停止吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    stop_activemq "$instance"
                    return 0
                fi
                return 1
                ;;
            3)
                read -p "确认要重启吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    restart_activemq "$instance"
                fi
                return 1 
                ;;
            0|b|B)
                return 1
                ;;
            *)
                echo -e "${RED}无效的选择${NC}"
                ;;
        esac
    done
}

# ===== Redis服务专用函数 =====
get_redis_password() {
    local instance=$1
    local redis_path_var="${instance}_workdir"
    local redis_conf_file_var="${instance}_conf_file"

    local redis_path="${!redis_path_var}"
    local _redis_conf_file="${!redis_conf_file_var}"
    local redis_conf_file=$(join_paths "$redis_path" "$_redis_conf_file")

    if [ ! -f "$redis_conf_file" ]; then
        echo "${RED}错误: Redis配置文件不存在: '$redis_conf_file'${NC}"
        return 1
    fi
    local password_var=$(grep "^requirepass" "$redis_conf_file" | awk '{print $2}')
    if [ -z "$password_var" ]; then
        echo ""
    else
        echo "$password_var"
    fi
    return 0
}

get_redis_port() {
    local instance=$1
    local redis_path_var="${instance}_workdir"
    local redis_conf_file_var="${instance}_conf_file"

    local redis_path="${!redis_path_var}"
    local _redis_conf_file="${!redis_conf_file_var}"
    local redis_conf_file=$(join_paths "$redis_path" "$_redis_conf_file")

    if [ ! -f "$redis_conf_file" ]; then
        echo "${RED}错误: Redis配置文件不存在: '$redis_conf_file'${NC}"
        return 1
    fi

    local port_var=$(grep "^port" "$redis_conf_file" | awk '{print $2}')
    if [ -z "$port_var" ]; then
        echo "6379"
    else
        echo "$port_var"
    fi
    return 0
}

get_redis_status() { 
    local instance=$1
    local name_var="${instance}_name"
    local redis_path_var="${instance}_workdir"
    local redis_conf_file_var="${instance}_conf_file"
    local redis_cmd_var="${instance}_cmd"
    
    local name="${!name_var}"
    local redis_path="${!redis_path_var}"
    local _redis_conf_file="${!redis_conf_file_var}"
    # 修复这里的错误: 使用redis_path而不是activemq_path
    local redis_conf_file=$(join_paths "$redis_path" "$_redis_conf_file")
    # 如果redis_cmd未定义，则使用默认值
    if [ -n "${!redis_cmd_var}" ]; then
        local redis_cmd="${!redis_cmd_var}"
    else
        local redis_cmd="$redis_path/bin/redis-cli"
    fi
    
    # 获取进程状态
    local pid=$(get_service_pid $instance)
    local status_text="${RED}未运行${NC}"
    local version_info=""
    local mem_usage=""
    local uptime=""
    local port=$(get_redis_port "$instance")
    local password=$(get_redis_password "$instance")
    local connected_clients="0"
    local redis_mode="standalone"
    
    if [ -n "$pid" ]; then
        status_text="${GREEN}运行中${NC}"
        
        # 获取版本信息
        if [ -x "$redis_path/bin/redis-server" ]; then
            version_info=$($redis_path/bin/redis-server --version 2>&1 | grep -oP "v=\K[0-9]+\.[0-9]+\.[0-9]+" || echo "未知")
        fi
        
        # 获取内存使用
        mem_usage=$(ps -o rss= -p $pid 2>/dev/null)
        if [ -n "$mem_usage" ]; then
            mem_usage=$(awk "BEGIN {printf \"%.2f MB\", $mem_usage/1024}")
        else
            mem_usage="未知"
        fi
        
        # 使用redis-cli获取详细信息
        if [ -x "$redis_cmd" ]; then
            local auth_param=""
            if [ -n "$password" ]; then
                auth_param="-a $password"
            fi
            
            # 获取INFO命令输出
            local redis_info=$(timeout 2 $redis_cmd -p $port $auth_param INFO 2>/dev/null)
            
            if [ -n "$redis_info" ]; then
                # 解析运行时间（以秒为单位）
                local uptime_sec=$(echo "$redis_info" | grep "uptime_in_seconds" | cut -d':' -f2 | tr -d '\r\n ')
                if [[ -n "$uptime_sec" && "$uptime_sec" =~ ^[0-9]+$ ]]; then
                    # 确保uptime_sec是纯数字
                    local days=$(( uptime_sec / 86400 ))
                    local hours=$(( (uptime_sec % 86400) / 3600 ))
                    local minutes=$(( (uptime_sec % 3600) / 60 ))
                    uptime="${days}天${hours}小时${minutes}分钟"
                else
                    uptime="未知"
                fi
                
                # 获取已连接客户端数量
                connected_clients=$(echo "$redis_info" | grep "connected_clients" | cut -d':' -f2)
                if [ -z "$connected_clients" ]; then
                    connected_clients="未知"
                fi
                
                # 获取已使用内存
                local used_memory=$(echo "$redis_info" | grep "used_memory_human" | cut -d':' -f2)
                if [ -n "$used_memory" ]; then
                    mem_usage="$used_memory"
                fi
                
                # 获取Redis模式（单机/集群/哨兵）
                redis_mode=$(echo "$redis_info" | grep "redis_mode" | cut -d':' -f2 | tr -d '\r')
                if [ -z "$redis_mode" ]; then
                    redis_mode="standalone"
                fi
            fi
        fi
        
        echo -e "运行状态: ${GREEN}$status_text${NC} 运行时间: ${GREEN}$uptime${NC}"
        echo -e "PID: ${GREEN}$pid${NC} | 版本: ${GREEN}$version_info${NC}"
        echo -e "端口: ${GREEN}$port${NC} | CLI连接数: ${GREEN}$connected_clients${NC}"
        echo -e "内存: ${GREEN}$mem_usage${NC}"
        
        # 如果是集群模式，显示集群信息
        if [ "$redis_mode" == "cluster" ]; then
            echo -e "\n集群节点信息:"
            local auth_param=""
            if [ -n "$password" ]; then
                auth_param="-a $password"
            fi
            $redis_cmd -p $port $auth_param CLUSTER NODES 2>/dev/null | awk '{print $2, $3, $4}' | while read line; do
                if [ -n "$line" ]; then
                    echo -e "  ${GREEN}$line${NC}"
                fi
            done
        fi
    else
        echo -e "${RED}运行状态: $status_text${NC}"
        if [ -f "$redis_conf_file" ]; then
            echo -e "配置文件: ${YELLOW}$redis_conf_file${NC} | 端口: ${YELLOW}$port${NC}"
        else
            echo -e "配置文件: ${RED}未找到${NC} | 默认端口: ${YELLOW}$port${NC}"
        fi
    fi
    
    return 0
}

# Redis服务启动
start_redis() {
    local instance=$1
    local name_var="${instance}_name"
    local redis_path_var="${instance}_workdir"
    local redis_conf_file_var="${instance}_conf_file"
    local redis_cmd_var="${instance}_cmd"
    
    local name="${!name_var}"
    local redis_path="${!redis_path_var}"
    local _redis_conf_file="${!redis_conf_file_var}"
    local redis_conf_file=$(join_paths "$redis_path" "$_redis_conf_file")
    local port=$(get_redis_port "$instance")
    
    # 检查进程状态
    local pid=$(get_service_pid $instance)
    if [ -n "$pid" ]; then
        echo -e "${YELLOW}[$name] Redis服务已经在运行中 (PID: $pid)${NC}"
        return 0
    fi
    
    # 检查必要的文件和目录
    if [ ! -d "$redis_path" ]; then
        echo -e "${RED}错误: Redis工作目录不存在: '$redis_path'${NC}"
        return 1
    fi
    
    if [ ! -f "$redis_conf_file" ]; then
        echo -e "${RED}错误: Redis配置文件不存在: '$redis_conf_file'${NC}"
        return 1
    fi
    
    if [ ! -x "$redis_path/bin/redis-server" ]; then
        echo -e "${RED}错误: Redis可执行文件不存在或没有执行权限: '$redis_path/bin/redis-server'${NC}"
        return 1
    fi
    
    if netstat -tln | grep -q ":$port "; then
        echo -e "${RED}错误: 端口 $port 已被占用，请检查${NC}"
        return 1
    fi
    
    echo -e "${BLUE}正在启动 Redis 服务...${NC}"
    
    # 切换到Redis工作目录
    cd "$redis_path" || return 1

    local redis_server_log="$redis_path/logs/redis-server.log"
    if [ ! -d "$redis_path/logs" ]; then
        mkdir -p "$redis_path/logs"
    fi
    if [ ! -f "$redis_server_log" ]; then
        touch "$redis_server_log"
    fi
    
    # 启动Redis服务
    nohup "$redis_path/bin/redis-server" "$redis_conf_file" > "$redis_server_log" 2>&1 &
    
    # 等待服务启动
    local start_time=$SECONDS
    local timeout=10
    local started=false
    
    echo -n "等待服务启动"
    while [ $((SECONDS - start_time)) -lt $timeout ]; do
        echo -n "."
        sleep 1
        
        # 检查Redis是否已启动
        if netstat -tln | grep -q ":$port "; then
            started=true
            break
        fi
    done
    echo ""
    
    if $started; then
        pid=$(get_service_pid $instance)
        echo -e "${GREEN}Redis服务已成功启动 (PID: $pid)${NC}"
        return 0
    else
        echo -e "${RED}Redis服务启动失败或超时${NC}"
        echo "检查日志: $redis_server_log"
        tail -n 10 "$redis_server_log"
        return 1
    fi
}

# Redis服务停止
stop_redis() {
    local instance=$1
    local name_var="${instance}_name"
    local redis_path_var="${instance}_workdir"
    local redis_conf_file_var="${instance}_conf_file"
    
    local name="${!name_var}"
    local redis_path="${!redis_path_var}"
    local _redis_conf_file="${!redis_conf_file_var}"
    local redis_conf_file=$(join_paths "$redis_path" "$_redis_conf_file")
    local port=$(get_redis_port "$instance")
    local password=$(get_redis_password "$instance")
    
    # 检查进程状态
    local pid=$(get_service_pid $instance)
    if [ -z "$pid" ]; then
        echo -e "${YELLOW}[$name] Redis服务未运行${NC}"
        return 0
    fi
    
    echo -e "${BLUE}正在停止 Redis 服务...${NC}"
    
    local auth_cmd=""
    if [ -n "$password" ]; then
        auth_cmd="-a $password"
    fi
    
    # 尝试正常关闭Redis
    if [ -x "$redis_path/bin/redis-cli" ]; then
        echo -e "使用redis-cli关闭服务..."
        "$redis_path/bin/redis-cli" -p $port $auth_cmd shutdown SAVE
        sleep 2
        
        # 检查是否成功关闭
        if ! ps -p $pid > /dev/null 2>&1; then
            echo -e "${GREEN}Redis服务已成功停止${NC}"
            return 0
        fi
    fi
    
    # 如果正常关闭失败，尝试发送SIGTERM信号
    echo -e "尝试使用SIGTERM信号关闭..."
    kill $pid
    
    # 等待进程终止
    local count=0
    while [ $count -lt 10 ]; do
        if ! ps -p $pid > /dev/null 2>&1; then
            echo -e "${GREEN}Redis服务已成功停止${NC}"
            return 0
        fi
        echo -n "."
        sleep 1
        count=$((count + 1))
    done
    
    # 如果SIGTERM无效，使用SIGKILL强制终止
    echo -e "\n${YELLOW}警告: 服务无响应，强制终止进程...${NC}"
    kill -9 $pid
    sleep 1
    
    if ! ps -p $pid > /dev/null 2>&1; then
        echo -e "${GREEN}Redis服务已强制终止${NC}"
        return 0
    else
        echo -e "${RED}错误: 无法终止Redis服务${NC}"
        return 1
    fi
}

# Redis服务重启
restart_redis() {
    local instance=$1
    local name_var="${instance}_name"
    local name="${!name_var}"
    
    echo -e "${BLUE}正在重启 Redis 服务...${NC}"
    
    stop_redis "$instance"
    sleep 2
    start_redis "$instance"
    
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}Redis服务已成功重启${NC}"
        return 0
    else
        echo -e "${RED}错误: Redis服务重启失败${NC}"
        return 1
    fi
}

view_redis_log() {
    local instance=$1
    local redis_path_var="${instance}_workdir"
    local redis_log_file_var="${instance}_log_file"

    local redis_path="${!redis_path_var}"
    local _redis_log_file="${!redis_log_file_var}"
    local redis_log_file=$(join_paths "$redis_path" "$_redis_log_file")
    
    if [ ! -f "$redis_log_file" ]; then
        echo -e "${RED}错误: Redis日志文件不存在: '$redis_log_file'${NC}"
        return 1
    fi
    
    echo -e "${BLUE}正在查看 Redis 日志: $redis_log_file${NC}"
    less "$redis_log_file"
}

show_redis_menu() {
    local instance=$1
    local name_var="${instance}_name"
    local name="${!name_var}"
    while true; do 
        clear
        echo -e "${BLUE}===============================================${NC}"
        echo -e "${YELLOW}        Redis管理: $name            ${NC}"
        echo -e "${BLUE}===============================================${NC}"

        get_redis_status "$instance"

        echo -e "${BLUE}-----------------------------------------------${NC}"
        echo -e "${YELLOW}1)${NC} 启动服务"
        echo -e "${YELLOW}2)${NC} 停止服务"
        echo -e "${YELLOW}3)${NC} 重启服务"
        echo -e "${YELLOW}4)${NC} 查看日志"
        echo -e "${YELLOW}5)${NC} 查看密码"
        echo -e "${YELLOW}0)${NC} 返回主菜单"
        echo -e "${BLUE}-----------------------------------------------${NC}"
        read -e -p "请选择操作: " op
        case "$op" in
            1) 
                read -p "确认要启动吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    start_redis "$instance"
                fi
                return 1
                ;;
            2)
                read -p "确认要停止吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    stop_redis "$instance"
                fi
                return 1
                ;;
            3)
                read -p "确认要重启吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    restart_redis "$instance"
                fi
                return 1
                ;;
            4)
                view_redis_log "$instance"
                return 1
                ;;
            5)
                local password=$(get_redis_password "$instance")
                if [ -n "$password" ]; then
                    echo -e "${GREEN}Redis密码: $password${NC}"
                else
                    echo -e "${YELLOW}Redis未设置密码${NC}"
                fi
                read -p "按任意键继续..."
                return 1
                ;;
            0|b|B)
                return 0
                ;;
            *)
                echo -e "${RED}无效的选择${NC}"
                ;;
        esac
    done
}

# ===== Memcached服务专用函数 =====
get_memcached_status() {
    local instance=$1
    local name_var="${instance}_name"
    local memcached_path_var="${instance}_workdir"
    local port_var="${instance}_port"
    
    local name="${!name_var}"
    local memcached_path="${!memcached_path_var}"
    local port="${!port_var:-11211}"
    
    # 获取进程状态
    local pid=$(get_service_pid $instance)
    local status_text="${RED}未运行${NC}"
    local version_info=""
    local mem_usage=""
    local uptime=""
    local connections=0
    local used_mem="0MB"
    local max_mem="0MB"
    
    if [ -n "$pid" ]; then
        status_text="${GREEN}运行中${NC}"
        
        # 获取版本信息
        if [ -x "$memcached_path/memcached" ]; then
            version_info=$($memcached_path/memcached -h 2>&1 | grep -oP "memcached \K[0-9]+\.[0-9]+\.[0-9]+" || echo "未知")
        fi
        
        # 获取内存使用
        mem_usage=$(ps -o rss= -p $pid 2>/dev/null)
        if [ -n "$mem_usage" ]; then
            mem_usage=$(awk "BEGIN {printf \"%.2f MB\", $mem_usage/1024}")
        else
            mem_usage="未知"
        fi
        
        # 获取运行时间
        if [ -n "$pid" ]; then
            local proc_start=$(ps -p $pid -o lstart= 2>/dev/null)
            if [ -n "$proc_start" ]; then
                local start_seconds=$(date -d "$proc_start" +%s)
                local current_seconds=$(date +%s)
                local seconds_running=$((current_seconds - start_seconds))
                local days=$((seconds_running / 86400))
                local hours=$(( (seconds_running % 86400) / 3600 ))
                local minutes=$(( (seconds_running % 3600) / 60 ))
                uptime="${days}天${hours}小时${minutes}分钟"
            else
                uptime="未知"
            fi
        fi
        
        # 尝试获取memcached状态信息（需要安装nc或telnet）
        if command -v nc >/dev/null 2>&1; then
            local stats=$(echo -e "stats\r\nquit" | nc localhost ${port} 2>/dev/null)
            if [ -n "$stats" ]; then
                connections=$(echo "$stats" | grep "curr_connections" | awk '{print $3}')
                used_mem=$(echo "$stats" | grep "bytes " | awk '{printf "%.2f MB", $3/1024/1024}')
                max_mem=$(echo "$stats" | grep "limit_maxbytes" | awk '{printf "%.2f MB", $3/1024/1024}')
            fi
        elif command -v telnet >/dev/null 2>&1; then
            local tmp_file=$(mktemp)
            (echo "stats"; echo "quit") | telnet localhost ${port} > $tmp_file 2>/dev/null 
            local stats=$(cat $tmp_file)
            rm -f $tmp_file
            
            if [ -n "$stats" ]; then
                connections=$(echo "$stats" | grep "curr_connections" | awk '{print $3}')
                used_mem=$(echo "$stats" | grep "bytes " | awk '{printf "%.2f MB", $3/1024/1024}')
                max_mem=$(echo "$stats" | grep "limit_maxbytes" | awk '{printf "%.2f MB", $3/1024/1024}')
            fi
        fi
        
        echo -e "运行状态: ${GREEN}$status_text${NC} 运行时间: ${GREEN}$uptime${NC}"
        echo -e "PID: ${GREEN}$pid${NC} | 版本: ${GREEN}$version_info${NC}"
        echo -e "端口: ${GREEN}$port${NC} | 当前连接数: ${GREEN}$connections${NC}"
        echo -e "内存使用: ${GREEN}$used_mem${NC} / ${GREEN}$max_mem${NC}"
    else
        echo -e "${RED}[$name] Memcached状态: $status_text${NC}"
        echo -e "端口: ${YELLOW}$port${NC}"
    fi
    
    return 0
}

start_memcached() {
    local instance=$1
    local name_var="${instance}_name"
    local memcached_path_var="${instance}_workdir"
    local port_var="${instance}_port"
    local cmd_var="${instance}_cmd"
    local memcached_pid_file_var="${instance}_pid_file"
    
    local name="${!name_var}"
    local memcached_path="${!memcached_path_var}"
    local port="${!port_var:-11211}"
    local exe_cmd="${!cmd_var}"
    local _memcached_pid_file="${!memcached_pid_file_var:-/tmp/memcached.pid}"
    local memcached_pid_file=$(join_paths "$memcached_path" "$_memcached_pid_file")

    if [ -z "$exe_cmd" ]; then
        exe_cmd="$memcached_path/memcached -d -m 1024 -u root -l 127.0.0.1 -p $port -c 1024 -P $memcached_pid_file"
    fi
    
    # 检查进程状态
    local pid=$(get_service_pid $instance)
    if [ -n "$pid" ]; then
        echo -e "${YELLOW}[$name] Memcached服务已经在运行中 (PID: $pid)${NC}"
        return 0
    fi
    
    # 检查必要的文件和目录
    if [ ! -d "$memcached_path" ]; then
        echo -e "${RED}错误: Memcached工作目录不存在: '$memcached_path'${NC}"
        return 1
    fi
    
    if [ ! -x "$memcached_path/memcached" ]; then
        echo -e "${RED}错误: Memcached可执行文件不存在或没有执行权限: '$memcached_path/memcached'${NC}"
        return 1
    fi
    
    # 检查端口是否被占用
    if netstat -tln | grep -q ":$port "; then
        echo -e "${RED}错误: 端口 $port 已被占用，请检查${NC}"
        return 1
    fi
    
    echo -e "${BLUE}正在启动 Memcached 服务...${NC}"
    
    # 创建日志目录
    local log_dir="/var/memcached/logs"
    if [ ! -d "$log_dir" ]; then
        mkdir -p "$log_dir"
    fi
    
    # 启动Memcached
    $exe_cmd > "$log_dir/memcached.log" 2>&1
    
    # 等待服务启动
    local start_time=$SECONDS
    local timeout=10
    local started=false
    
    echo -n "等待服务启动"
    while [ $((SECONDS - start_time)) -lt $timeout ]; do
        echo -n "."
        sleep 1
        
        # 检查Memcached是否已启动
        if netstat -tln | grep -q ":$port "; then
            started=true
            break
        fi
    done
    echo ""
    
    pid=$(get_service_pid $instance)
    if [ -n "$pid" ] && $started; then
        echo -e "${GREEN}Memcached服务已成功启动 (PID: $pid)${NC}"
        return 0
    else
        echo -e "${RED}Memcached服务启动失败或超时${NC}"
        echo "检查日志: $log_dir/memcached.log"
        return 1
    fi
}

stop_memcached() {
    local instance=$1
    local name_var="${instance}_name"
    local memcached_path_var="${instance}_workdir"
    local memcached_pid_file_var="${instance}_pid_file"
    
    local name="${!name_var}"
    local memcached_path="${!memcached_path_var}"
    local _memcached_pid_file="${!memcached_pid_file_var:-/tmp/memcached.pid}"
    local memcached_pid_file=$(join_paths "$memcached_path" "$_memcached_pid_file")
    
    # 检查进程状态
    local pid=$(get_service_pid $instance)
    if [ -z "$pid" ]; then
        echo -e "${YELLOW}[$name] Memcached服务未运行${NC}"
        return 0
    fi
    
    echo -e "${BLUE}正在停止 Memcached 服务...${NC}"
    
    # 尝试正常终止进程
    kill $pid
    
    # 等待进程终止
    local count=0
    while [ $count -lt 10 ]; do
        if ! ps -p $pid > /dev/null 2>&1; then
            echo -e "${GREEN}Memcached服务已成功停止${NC}"
            return 0
        fi
        echo -n "."
        sleep 1
        count=$((count + 1))
    done
    
    # 如果正常终止失败，强制终止
    echo -e "\n${YELLOW}警告: 服务无响应，尝试强制终止进程...${NC}"
    kill -9 $pid
    sleep 1
    
    if ! ps -p $pid > /dev/null 2>&1; then
        echo -e "${GREEN}Memcached服务已强制终止${NC}"
        
        # 清理PID文件
        if [ -f "$memcached_pid_file" ]; then
            rm -f "$memcached_pid_file"
        fi
        
        return 0
    else
        echo -e "${RED}错误: 无法终止Memcached服务${NC}"
        return 1
    fi
}

restart_memcached() {
    local instance=$1
    local name_var="${instance}_name"
    local name="${!name_var}"
    
    echo -e "${BLUE}正在重启 Memcached 服务...${NC}"
    
    stop_memcached "$instance"
    sleep 2
    start_memcached "$instance"
    
    if [ $? -eq 0 ]; then
        echo -e "${GREEN}Memcached服务已成功重启${NC}"
        return 0
    else
        echo -e "${RED}错误: Memcached服务重启失败${NC}"
        return 1
    fi
}

show_memcached_menu() {
    local instance=$1
    local name_var="${instance}_name"
    local name="${!name_var}"
    while true; do 
        clear
        echo -e "${BLUE}===============================================${NC}"
        echo -e "${YELLOW}        Memcached管理: $name            ${NC}"
        echo -e "${BLUE}===============================================${NC}"

        get_memcached_status "$instance"

        echo -e "${BLUE}-----------------------------------------------${NC}"
        echo -e "${YELLOW}1)${NC} 启动服务"
        echo -e "${YELLOW}2)${NC} 停止服务"
        echo -e "${YELLOW}3)${NC} 重启服务"
        echo -e "${YELLOW}0)${NC} 返回主菜单"
        echo -e "${BLUE}-----------------------------------------------${NC}"
        read -e -p "请选择操作: " op
        case "$op" in
            1) 
                read -p "确认要启动吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    start_memcached "$instance"
                fi
                break 
                ;;
            2)
                read -p "确认要停止吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    stop_memcached "$instance"
                fi
                break 
                ;;
            3)
                read -p "确认要重启吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    restart_memcached "$instance"
                fi
                break 
                ;;
            0|b|B)
                return 
                ;;
            *)
                echo -e "${RED}无效的选择${NC}"
                ;;
        esac
    done
}

# ===== Backup服务专用函数 =====
get_backup_status() {
    local instance=$1
    local workdir_var="${instance}_workdir"
    local backup_dir_var="${instance}_backup_dir"
    
    local workdir="${!workdir_var}"
    local _backup_dir="${!backup_dir_var}"
    local backup_dir=$(join_paths "$workdir" "$_backup_dir")
    
    echo -e "${YELLOW}源目录:${NC} $workdir"
    if [ -d "$workdir" ]; then
        # echo -e "${GREEN}源目录状态: 存在${NC}"
        echo -e "目录大小: $(du -sh "$workdir" 2>/dev/null | cut -f1)"
    else
        echo -e "${RED}源目录状态: 不存在${NC}"
    fi
    
    echo -e "\n${YELLOW}备份目录:${NC} $backup_dir"
    if [ -d "$backup_dir" ]; then
        # echo -e "${GREEN}备份目录状态: 存在${NC}"
        echo -e "备份文件数量: $(ls -1 "$backup_dir"/*.tar.gz 2>/dev/null | wc -l)"
        echo -e "备份目录大小: $(du -sh "$backup_dir" 2>/dev/null | cut -f1)"
    else
        echo -e "${RED}备份目录状态: 不存在${NC}"
    fi
}

# 执行目录备份
backup_folder() {
    local instance=$1
    local workdir_var="${instance}_workdir"
    local backup_dir_var="${instance}_backup_dir"
    local backup_file_var="${instance}_backup_file"
    
    local workdir="${!workdir_var}"
    local _backup_dir="${!backup_dir_var}"
    local backup_dir=$(join_paths "$workdir" "$_backup_dir")
    local backup_file="${!backup_file_var}"
    
    # 检查源目录
    if [ ! -d "$workdir" ]; then
        echo -e "${RED}错误: 源目录不存在 ($workdir)${NC}"
        return 1
    fi
    
    # 创建备份目录
    mkdir -p "$backup_dir"
    
    # 执行备份
    echo -e "${YELLOW}开始备份...${NC}"
    if tar -czf "$backup_dir/$backup_file" -C "$(dirname "$workdir")" "$(basename "$workdir")"; then
        echo -e "${GREEN}备份成功: $backup_dir/$backup_file${NC}"
        echo -e "备份文件大小: $(du -sh "$backup_dir/$backup_file" 2>/dev/null | cut -f1)"
    else
        echo -e "${RED}备份失败${NC}"
        return 1
    fi
}

# 查看备份
view_backup() {
    local instance=$1
    local workdir_var="${instance}_workdir"
    local backup_dir_var="${instance}_backup_dir"
    local workdir="${!workdir_var}"
    local _backup_dir="${!backup_dir_var}"
    local backup_dir=$(join_paths "$workdir" "$_backup_dir")
    
    if [ ! -d "$backup_dir" ]; then
        echo -e "${RED}备份目录不存在${NC}"
        return 1
    fi
    
    echo -e "${YELLOW}备份列表:${NC}"
    echo -e "${BLUE}-----------------------------------------------${NC}"
    ls -lht "$backup_dir"/*.tar.gz 2>/dev/null | awk '{print $6,$7,$8,$9}' || echo -e "${RED}没有找到备份文件${NC}"
    echo -e "${BLUE}-----------------------------------------------${NC}"
}

# 清理备份
clear_backup() {
    local instance=$1
    local workdir_var="${instance}_workdir"
    local backup_dir_var="${instance}_backup_dir"
    local workdir="${!workdir_var}"
    local _backup_dir="${!backup_dir_var}"
    local backup_dir=$(join_paths "$workdir" "$_backup_dir")
    
    if [ ! -d "$backup_dir" ]; then
        echo -e "${RED}备份目录不存在${NC}"
        return 1
    fi
    
    # 统计不同时间范围的文件
    local one_day_files=$(find "$backup_dir" -name "*.tar.gz" -mtime +1 2>/dev/null)
    local three_day_files=$(find "$backup_dir" -name "*.tar.gz" -mtime +3 2>/dev/null)
    local all_files=$(find "$backup_dir" -name "*.tar.gz" 2>/dev/null)
    
    # 计算文件数量（修改计数方法）
    local one_day_count=0
    local three_day_count=0
    local all_count=0
    
    [ -n "$one_day_files" ] && one_day_count=$(echo "$one_day_files" | wc -l)
    [ -n "$three_day_files" ] && three_day_count=$(echo "$three_day_files" | wc -l)
    [ -n "$all_files" ] && all_count=$(echo "$all_files" | wc -l)
    
    # 计算文件大小总和
    local one_day_size="0B"
    local three_day_size="0B"
    local all_size="0B"
    
    [ -n "$one_day_files" ] && one_day_size=$(du -ch $one_day_files 2>/dev/null | tail -n1 | cut -f1 || echo "0B")
    [ -n "$three_day_files" ] && three_day_size=$(du -ch $three_day_files 2>/dev/null | tail -n1 | cut -f1 || echo "0B")
    [ -n "$all_files" ] && all_size=$(du -ch $all_files 2>/dev/null | tail -n1 | cut -f1 || echo "0B")
    
    if [ $all_count -eq 0 ]; then
        echo -e "${YELLOW}没有找到需要清理的备份文件${NC}"
        return 0
    fi
    
    echo -e "${YELLOW}找到 $all_count 个备份文件, 共计大小: ${all_size} ${NC}"
    echo -e "${BLUE}-----------------------------------------------${NC}"
    echo -e "${YELLOW}1)${NC} 清理1天前的备份文件 (${one_day_count}个文件, 共${one_day_size})"
    echo -e "${YELLOW}2)${NC} 清理3天前的备份文件 (${three_day_count}个文件, 共${three_day_size})"
    echo -e "${YELLOW}3)${NC} 清理所有备份文件 (${all_count}个文件, 共${all_size})"
    echo -e "${YELLOW}0)${NC} 取消"
    echo -e "${BLUE}-----------------------------------------------${NC}"
    
    read -p "请选择清理方式: " clean_choice
    case "$clean_choice" in
       1)
            read -p "确认要清理1天前的备份文件吗？(y/n): " confirm
            if [ "$confirm" = "y" ]; then
                find "$backup_dir" -name "*.tar.gz" -mtime +1 -delete
                echo -e "${GREEN}已清理1天前的备份文件${NC}"
                read -p "按回车键继续..."
            fi
            ;;
        2)
            read -p "确认要清理3天前的备份文件吗？(y/n): " confirm
            if [ "$confirm" = "y" ]; then
                find "$backup_dir" -name "*.tar.gz" -mtime +3 -delete
                echo -e "${GREEN}已清理3天前的备份文件${NC}"
                read -p "按回车键继续..."
            fi
            ;;
        3)
            read -p "确认要清理所有备份文件吗？(y/n): " confirm
            if [ "$confirm" = "y" ]; then
                rm -f "$backup_dir"/*.tar.gz
                echo -e "${GREEN}已清理所有备份文件${NC}"
                read -p "按回车键继续..."
            fi
            ;;
        0)
            echo -e "${YELLOW}操作已取消${NC}"
            ;;
        *)
            echo -e "${RED}无效的选择${NC}"
            ;;
    esac
}

show_backup_menu() {
    local instance=$1
    local name_var="${instance}_name"
    local name="${!name_var}"
    while true; do 
        clear
        echo -e "${BLUE}===============================================${NC}"
        echo -e "${YELLOW}        目录备份管理: $name            ${NC}"
        echo -e "${BLUE}===============================================${NC}"

        get_backup_status "$instance"

        echo -e "${BLUE}-----------------------------------------------${NC}"
        echo -e "${YELLOW}1)${NC} 备份目录"
        echo -e "${YELLOW}2)${NC} 查看备份"
        echo -e "${YELLOW}3)${NC} 清理备份"
        echo -e "${YELLOW}0)${NC} 返回主菜单"
        echo -e "${BLUE}-----------------------------------------------${NC}"
        read -e -p "请选择操作: " op
        case "$op" in
            1) 
                read -p "确认要执行备份吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    backup_folder "$instance"
                    read -p "按回车键继续..."
                fi
                ;;
            2)
                view_backup "$instance"
                read -p "按回车键继续..."
                ;;
            3)
                clear_backup "$instance"
                ;;
            0|b|B)
                return 
                ;;
            *)
                echo -e "${RED}无效的选择${NC}"
                read -p "按回车键继续..."
                ;;
        esac
    done
}

# ===== Jar服务专用函数 =====
# 获取Java进程状态
get_javaJar_status() {
    local instance=$1
    local workdir_var="${instance}_workdir"
    local jar_file_var="${instance}_jar_file"
    local workdir="${!workdir_var}"
    local jar_file="${!jar_file_var}"

    echo -e "${YELLOW}服务状态:${NC} "
    if [ -z "$workdir" ] || [ -z "$jar_file" ]; then
        echo -e "${RED}配置错误：工作目录或JAR文件未配置${NC}"
        return 1
    fi

    local pid=$(pgrep -f "$jar_file")
    if [ -n "$pid" ]; then
        echo -e "${GREEN}运行中 (PID: $pid)${NC}"
        return 0
    else
        echo -e "${RED}已停止${NC}"
        return 1
    fi
}

# 启动Java程序
start_javaJar() {
    local instance=$1
    local workdir_var="${instance}_workdir"
    local jar_file_var="${instance}_jar_file"
    local java_home_var="${instance}_java_home"
    local log_file_var="${instance}_log_file"
    
    local workdir="${!workdir_var}"
    local jar_file="${!jar_file_var}"
    local _log_file="${!log_file_var}"
    local _java_home="${!java_home_var}"
    local java_home=$(join_paths "$workdir" "$_java_home")
    local log_file=$(join_paths "$workdir" "$_log_file")

    if [ -z "$workdir" ] || [ -z "$jar_file" ]; then
        echo -e "${RED}配置错误：工作目录或JAR文件未配置${NC}"
        return 1
    fi

    cd "$workdir" || {
        echo -e "${RED}无法进入工作目录: $workdir${NC}"
        return 1
    }

    if get_javaJar_status "$instance"; then
        echo -e "${YELLOW}服务已在运行中${NC}"
        return 0
    fi

    # 创建日志目录
    mkdir -p "$(dirname "$log_file")"
    
    # 启动服务
    nohup "$java_home/bin/java" -jar "$jar_file" > "$log_file" 2>&1 &
    
    sleep 2
    if get_javaJar_status "$instance"; then
        echo -e "${GREEN}服务启动成功${NC}"
    else
        echo -e "${RED}服务启动失败${NC}"
    fi
}

# 停止Java程序
stop_javaJar() {
    local instance=$1
    local jar_file_var="${instance}_jar_file"
    local jar_file="${!jar_file_var}"

    local pid=$(pgrep -f "$jar_file")
    if [ -n "$pid" ]; then
        kill "$pid"
        sleep 2
        if ! get_javaJar_status "$instance"; then
            echo -e "${GREEN}服务已停止${NC}"
        else
            echo -e "${RED}服务停止失败，尝试强制停止${NC}"
            kill -9 "$pid"
        fi
    else
        echo -e "${YELLOW}服务未运行${NC}"
    fi
}

# 重启Java程序
restart_javaJar() {
    local instance=$1
    echo -e "${YELLOW}正在停止服务...${NC}"
    stop_javaJar "$instance"
    sleep 2
    echo -e "${YELLOW}正在启动服务...${NC}"
    start_javaJar "$instance"
}

# 查看Java程序日志
view_javaJar_log() {
    local instance=$1
    local log_file_var="${instance}_log_file"
    local _log_file="${!log_file_var}"
    local log_file=$(join_paths "$workdir" "$_log_file")

    if [ -f "$log_file" ]; then
        tail -f "$log_file"
    else
        echo -e "${RED}日志文件不存在: $log_file${NC}"
    fi
}

show_jar_menu() {
    local instance=$1
    local name_var="${instance}_name"
    local name="${!name_var}"
    while true; do 
        clear
        echo -e "${BLUE}===============================================${NC}"
        echo -e "${YELLOW}       JavaJar程序管理: $name            ${NC}"
        echo -e "${BLUE}===============================================${NC}"

        get_javaJar_status "$instance"

        echo -e "${BLUE}-----------------------------------------------${NC}"
        echo -e "${YELLOW}1)${NC} 运行Java Jar Package"
        echo -e "${YELLOW}2)${NC} 停止Java Jar Package"
        echo -e "${YELLOW}3)${NC} 重启Java Jar Package"
        echo -e "${YELLOW}4)${NC} 查看日志"
        echo -e "${YELLOW}0)${NC} 返回主菜单"
        echo -e "${BLUE}-----------------------------------------------${NC}"
        read -e -p "请选择操作: " op
        case "$op" in
            1) 
                read -p "确认要运行吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    start_javaJar "$instance"
                    read -p "按回车键继续..."
                fi
                ;;
            2)
                read -p "确认要停止吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    stop_javaJar "$instance"
                    read -p "按回车键继续..."
                fi
                ;;
            3)
                read -p "确认要重启吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    restart_javaJar "$instance"
                fi
                ;;
            4)
                view_javaJar_log "$instance"
                read -p "按回车键继续..."
                ;;
            0|b|B)
                return 
                ;;
            *)
                echo -e "${RED}无效的选择${NC}"
                read -p "按回车键继续..."
                ;;
        esac
    done
}

# ===== ApusicAS(金蝶)服务专用函数 =====
# 获取金蝶服务状态
get_aas_status() {
    local instance=$1
    local workdir_var="${instance}_workdir"
    local port_var="${instance}_port"
    local test_url_var="${instance}_test_url"

    local workdir="${!workdir_var}"
    local port="${!port_var}"
    local test_url="${!test_url_var}"

    echo -e "${YELLOW}服务状态:${NC} "
    
    # 检查端口
    if ! netstat -tuln | grep -q ":$port\b"; then
        echo -e "${RED}端口 $port 未监听${NC}"
        return 1
    fi

    # 检查进程
    local pid=$(ps aux | grep "asadmin" | grep "$workdir" | awk '{print $2}')
    if [ -n "$pid" ]; then
        echo -e "${GREEN}运行中 (PID: $pid)${NC}"
        # 测试URL可访问性
        if curl -s --head "$test_url" >/dev/null; then
            echo -e "${GREEN}服务正常响应${NC}"
        else
            echo -e "${YELLOW}警告: 服务运行但URL无响应${NC}"
        fi
        return 0
    else
        echo -e "${RED}已停止${NC}"
        return 1
    fi
}

# 启动金蝶服务
start_aas() {
    local instance=$1
    local workdir_var="${instance}_workdir"
    local workdir="${!workdir_var}"

    cd "$workdir" || {
        echo -e "${RED}无法进入工作目录: $workdir${NC}"
        return 1
    }

    if get_aas_status "$instance"; then
        echo -e "${YELLOW}服务已在运行中${NC}"
        return 0
    fi

    echo -e "${GREEN}正在启动服务...${NC}"
    nohup "$workdir/bin/asadmin start-domain" > /dev/null 2>&1 &
    
    # 等待服务启动
    local count=0
    while [ $count -lt 30 ]; do
        if get_aas_status "$instance"; then
            echo -e "${GREEN}服务启动成功${NC}"
            return 0
        fi
        echo -n "."
        sleep 2
        count=$((count + 1))
    done
    echo -e "${RED}服务启动超时${NC}"
    return 1
}

# 停止金蝶服务
stop_aas() {
    local instance=$1
    local workdir_var="${instance}_workdir"
    local workdir="${!workdir_var}"

    if ! get_aas_status "$instance"; then
        echo -e "${YELLOW}服务已经停止${NC}"
        return 0
    fi

    echo -e "${GREEN}正在停止服务...${NC}"
    nohup "$workdir/bin/asadmin stop-domain" > /dev/null 2>&1 &

    local count=0
    while [ $count -lt 15 ]; do
        if ! get_aas_status "$instance"; then
            echo -e "${GREEN}服务已停止${NC}"
            return 0
        fi
        echo -n "."
        sleep 2
        count=$((count + 1))
    done

    # 如果正常停止失败，强制结束进程
    local pid=$(ps aux | grep "asadmin" | grep "$workdir" | awk '{print $2}')
    if [ -n "$pid" ]; then
        echo -e "${YELLOW}正在强制停止进程...${NC}"
        kill -9 "$pid"
    fi
}

# 重启金蝶服务
restart_aas() {
    local instance=$1
    local workdir_var="${instance}_workdir"
    local workdir="${!workdir_var}"

    echo -e "${YELLOW}正在重启服务...${NC}"
    nohup "$workdir/bin/asadmin restart-domain" > /dev/null 2>&1 &

    sleep 5
    # 等待服务启动
    local count=0
    while [ $count -lt 30 ]; do
        if get_aas_status "$instance"; then
            echo -e "${GREEN}服务启动成功${NC}"
            return 0
        fi
        echo -n "."
        sleep 2
        count=$((count + 1))
    done
    echo -e "${RED}服务启动超时${NC}"
    return 1
}

# 查看金蝶服务日志
view_aas_log() {
    local instance=$1
    local log_file_var="${instance}_log_file"
    local _log_file="${!log_file_var}"
    local log_file=$(join_paths "${!instance}_workdir" "$_log_file")

    if [ -f "$log_file" ]; then
        tail -f "$log_file"
    else
        echo -e "${RED}日志文件不存在: $log_file${NC}"
    fi
}

show_aas_menu() {
    local instance=$1
    local name_var="${instance}_name"
    local name="${!name_var}"
    while true; do 
        clear
        echo -e "${BLUE}===============================================${NC}"
        echo -e "${YELLOW}       aas金蝶管理: $name            ${NC}"
        echo -e "${BLUE}===============================================${NC}"

        get_aas_status "$instance"

        echo -e "${BLUE}-----------------------------------------------${NC}"
        echo -e "${YELLOW}1)${NC} 启动服务"
        echo -e "${YELLOW}2)${NC} 停止服务"
        echo -e "${YELLOW}3)${NC} 重启服务"
        echo -e "${YELLOW}4)${NC} 查看日志"
        echo -e "${YELLOW}0)${NC} 返回主菜单"
        echo -e "${BLUE}-----------------------------------------------${NC}"
        read -e -p "请选择操作: " op
        case "$op" in
            1) 
                read -p "确认要启动吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    start_aas "$instance"
                    read -p "按回车键继续..."
                fi
                ;;
            2)
                read -p "确认要停止吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    stop_aas "$instance"
                    read -p "按回车键继续..."
                fi
                ;;
            3)
                read -p "确认要重启吗？(y|n): " confirm
                if [ "$confirm" = "y" ]; then
                    restart_aas "$instance"
                fi
                ;;
            4)
                view_aas_log "$instance"
                read -p "按回车键继续..."
                ;;
            0|b|B)
                return 
                ;;
            *)
                echo -e "${RED}无效的选择${NC}"
                read -p "按回车键继续..."
                ;;
        esac
    done
}

# ===== 更多专用函数 =====
# 获取系统信息
show_system_info() {
    # 内存信息
    local mem_total=$(free -k | awk 'NR==2{printf "%.1f", $2/1024/1024}')
    local mem_used=$(free -k | awk 'NR==2{printf "%.1f", $3/1024/1024}')
    local mem_free=$(free -k | awk 'NR==2{printf "%.1f", $4/1024/1024}')
    local mem_percent=$(awk "BEGIN {printf \"%.1f\", ($mem_used/$mem_total)*100}")
    echo -e "内存: 总计: ${mem_total}GB | ${GREEN}已用${NC}: ${mem_used}GB (${mem_percent}%) | ${GREEN}空闲${NC}: ${mem_free}GB"
    
    # CPU信息 - 修正计算方法
    local cpu_cores=$(nproc)
    # 使用mpstat或vmstat获取更准确的CPU使用率
    if command -v mpstat >/dev/null 2>&1; then
        # 使用mpstat获取CPU使用信息，计算用户空间+系统空间的百分比
        local cpu_idle=$(mpstat 1 1 | awk '$12 ~ /[0-9.]+/ {print $12}' | tail -1)
        local cpu_usage=$(awk "BEGIN {printf \"%.1f\", 100-$cpu_idle}")
    else
        # 回退方案: 使用top
        local cpu_usage=$(top -bn1 | grep "Cpu(s)" | \
                         sed "s/.*, *\([0-9.]*\)%* id.*/\1/" | \
                         awk '{printf "%.1f", 100-$1}')
    fi
    local cpu_idle_percent=$(awk "BEGIN {printf \"%.1f\", 100-$cpu_usage}")
    
    echo -e "CPU:  核心数: ${cpu_cores} | ${GREEN}使用率${NC}: ${cpu_usage}% | ${GREEN}空闲率${NC}: ${cpu_idle_percent}%" # Used renamed variable
    
    # 硬盘信息
    echo -e "硬盘使用情况:"
    df -h / | awk 'NR>1 {printf "  %-12s: 总计: %-6s | 已用: %-6s | 空闲: %-6s | 使用率: %-6s | 挂载点: %s\n", $1, $2, $3, $4, $5, $6}'
    df -h | awk 'NR>1 && $1 ~ /^\/dev/ && $6 != "/" {printf "  %-12s: 总计: %-6s | 已用: %-6s | 空闲: %-6s | 使用率: %-6s | 挂载点: %s\n", $1, $2, $3, $4, $5, $6}'
}

# 编辑服务配置文件
edit_service_config() {
    clear
    echo -e "${BLUE}===============================================${NC}"
    echo -e "${YELLOW}              编辑服务配置                    ${NC}"
    echo -e "${BLUE}===============================================${NC}"

    if [ ! -f "$CONFIG_FILE" ]; then
        echo -e "${RED}配置文件不存在，请创建：$CONFIG_FILE${NC}"
        return 1
    fi

    # 备份配置文件
    cp "$CONFIG_FILE" "${CONFIG_FILE}.bak"

    # 检查可用的编辑器
    local editors=("nano" "vim" "vi")
    local editor=""
    
    for e in "${editors[@]}"; do
        if command -v "$e" >/dev/null 2>&1; then
            editor="$e"
            break
        fi
    done

    if [ -z "$editor" ]; then
        echo -e "${RED}未找到可用的文本编辑器（需要nano、vim或vi）${NC}"
        return 1
    fi

    echo -e "${YELLOW}使用 $editor 编辑器打开配置文件...${NC}"
    echo -e "${BLUE}提示：编辑完成后按 Ctrl+X (nano) 或 :wq (vim) 保存并退出${NC}"
    sleep 1

    # 使用选定的编辑器打开配置文件
    $editor "$CONFIG_FILE"
    
    if [ $? -ne 0 ]; then
        echo -e "${RED}编辑配置文件失败。${NC}"
        echo -e "${YELLOW}是否恢复备份？(y/n)${NC}"
        read -p "" restore
        if [ "$restore" = "y" ]; then
            mv "${CONFIG_FILE}.bak" "$CONFIG_FILE"
            echo -e "${GREEN}已恢复备份文件。${NC}"
        fi
        return 1
    fi

    # 检查文件语法
    if ! bash -n "$CONFIG_FILE" >/dev/null 2>&1; then
        echo -e "${RED}配置文件包含语法错误！${NC}"
        echo -e "${YELLOW}是否恢复备份？(y/n)${NC}"
        read -p "" restore
        if [ "$restore" = "y" ]; then
            mv "${CONFIG_FILE}.bak" "$CONFIG_FILE"
            echo -e "${GREEN}已恢复备份文件。${NC}"
            return 1
        fi
    fi

    # 清理备份文件
    rm -f "${CONFIG_FILE}.bak"
    echo -e "${GREEN}配置文件已保存。${NC}"
    
    # 重新加载配置
    source "$CONFIG_FILE"
    echo -e "${GREEN}配置已重新加载。${NC}"
    return 0
}

# 获取服务简要信息
get_service_brief_info() {
    local instance=$1
    local type_var="${instance}_type"
    local type="${!type_var}"
    local port_var="${instance}_port"
    local port="${!port_var}"
    local workdir_var="${instance}_workdir"
    local workdir="${!workdir_var}"
    
    case "$type" in
        "tomcat"|"aas"|"tongweb")
            if [ -n "$port" ] && netstat -tuln | grep -q ":$port\b"; then
                echo -e "${GREEN}运行中${NC} [端口:$port]"
            else
                echo -e "${RED}已停止${NC}"
            fi
            ;;
        "nginx"|"activemq"|"memcached"|"redis")
            local pid=$(get_service_pid "$instance")
            if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
                if [ -n "$port" ] && netstat -tuln | grep -q ":$port\b"; then
                    echo -e "${GREEN}运行中${NC} [端口:$port]"
                else
                    echo -e "${GREEN}运行中${NC}"
                fi
            else
                echo -e "${RED}已停止${NC}"
            fi
            ;;
        "jar")
            local jar_file="${!instance}_jar_file"
            if pgrep -f "$jar_file" >/dev/null; then
                echo -e "${GREEN}运行中${NC}"
            else
                echo -e "${RED}已停止${NC}"
            fi
            ;;
        "backup")
            local backup_var="${instance}_backup_dir"
            local _backup_dir="${!backup_var}"
            local backup_dir=$(join_paths "$workdir" "$_backup_dir")

            if [ -d "$backup_dir" ]; then
                local count=$(ls -1 "$backup_dir" 2>/dev/null | wc -l)
                if [ $count -eq 0 ]; then
                    echo -e "${RED}未备份${NC}"
                else
                    local size=$(du -sh "$backup_dir" 2>/dev/null | cut -f1)
                    local last_file=$(ls -t "$backup_dir" 2>/dev/null | head -n 1)
                    local last_date=""
                    if [ -n "$last_file" ]; then
                        last_date=$(stat -c '%Y' "$backup_dir/$last_file" | xargs -I{} date -d @{} '+%Y%m%d %H:%M:%S')
                    fi
                    printf "%s" "已备份${count}次 | ${size} | ${last_date}"
                fi
            else
                echo -e "${RED}备份目录不存在${NC}"
            fi
            ;;
        *)
            echo -e "${YELLOW}未知类型${NC}"
            ;;
    esac
}

handle_service_menu() {
    local instance=$1
    local type_var="${instance}_type"
    local type_val="${!type_var}"
    
    case "$type_val" in
        "tomcat")
            show_tomcat_menu "$instance"
            ;;
        "nginx")
            show_nginx_menu "$instance"
            ;;
        "activemq")
            show_activemq_menu "$instance"
            ;;
        "redis")
            show_redis_menu "$instance"
            ;;
        "memcached")
            show_memcached_menu "$instance"
            ;;
        "backup")
            show_backup_menu "$instance"
            ;;
        "jar")
            show_jar_menu "$instance"
            ;;
        "aas")
            show_aas_menu "$instance"
            ;;
        "tongweb")
            echo -e "${RED}错误: Tongweb服务管理功能尚未实现${NC}"
            ;;
        "springboot")
            echo -e "${RED}错误: SpringBoot服务管理功能尚未实现${NC}"
            ;;
        "linrungtask")
            echo -e "${RED}错误: LinRungTask服务管理功能尚未实现${NC}"
            ;;
        *)
            echo -e "${RED}错误: 不支持的服务类型 '${type_val}' (来自变量 ${type_var})${NC}"
            ;;
    esac
}

# ===== 主菜单专用函数 =====
# 显示系统Java环境信息
show_system_java_home() {
    local _java_home=$(get_service_java_home "$1")
    if [ -n "$_java_home" ]; then
        echo -e "${BLUE}-----------------------------------------------${NC}"
        local _java_version=$("$_java_home/bin/java" -version 2>&1 | awk -F '"' '/version/ {print $2}')
        echo -e "${YELLOW}Java版本: ${NC}$_java_version"
        echo -e "${YELLOW}Java环境: ${NC}$_java_home"
    fi
}

# 显示主菜单
show_menu() {
    local _system_java_home=$(get_system_java_home "$1")

    clear
    echo -e "${BLUE}===============================================${NC}"
    echo -e "${YELLOW}              服务管理面板                    ${NC}"
    echo -e "${BLUE}===============================================${NC}"
    
    show_system_info
    if [ -n "$_system_java_home" ]; then
        show_system_java_home
    fi

    echo -e "${BLUE}-----------------------------------------------${NC}"
    for i in "${!APP_LIST[@]}"; do
        local idx=$((i+1))
        local instance="${APP_LIST[$i]}"
        local name="${instance}_name"
        local type="${instance}_type"
        printf "${YELLOW}%-3s${NC} %s (${YELLOW}%s${NC}) %s\n" \
            "$idx)" \
            "${!name}" \
            "${!type}" \
            "$(get_service_brief_info "$instance")"
    done
    echo -e "${BLUE}-----------------------------------------------${NC}"
    echo -e "${YELLOW}99)${NC} 编辑服务配置"
    echo -e "${YELLOW}0)${NC} 退出"
    echo -e "${BLUE}-----------------------------------------------${NC}"
}

# 主循环
while true; do
    show_menu
    read -p "请选择操作: " choice
    
    if [ "$choice" = "99" ]; then
        edit_service_config
    elif [ "$choice" = "0" ] || [ "$choice" = "b" ]; then
        echo -e "${GREEN}退出程序...${NC}"
        exit 0
    elif [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -gt 0 ] && [ "$choice" -le "${#APP_LIST[@]}" ]; then
        instance=${APP_LIST[$((choice-1))]}
        handle_service_menu "$instance"
    else
        echo -e "${RED}无效的选择${NC}"
    fi
    
    read -p "按回车键继续..."
done